/**
 * PANDA 3D SOFTWARE
 * Copyright (c) Carnegie Mellon University.  All rights reserved.
 *
 * All use of this software is subject to the terms of the revised BSD
 * license.  You should have received a copy of this license along
 * with this source code in a file named "LICENSE."
 *
 * @file projectionScreen.I
 * @author drose
 * @date 2001-12-11
 */

/**
 * Returns the NodePath to the LensNode that is to serve as the projector for
 * this screen, or empty if no projector is associated.
 */
INLINE const NodePath &ProjectionScreen::
get_projector() const {
  return _projector;
}

/**
 * Removes the distortion lookup table from the projector, if specified.
 */
INLINE void ProjectionScreen::
clear_undist_lut() {
  _has_undist_lut = false;
  _undist_lut = PfmFile();
}

/**
 * Applies a distortion lookup table to the projector.  This mapping warps the
 * lens effect by passing each ray through an indirection table: the point
 * (u,v) in the indicated lookup table stores the actual (u,v) that the lens
 * produces.
 *
 * This does not affect the operation of generate_screen().
 */
INLINE void ProjectionScreen::
set_undist_lut(const PfmFile &undist_lut) {
  _has_undist_lut = undist_lut.is_valid();
  _undist_lut = undist_lut;
}

/**
 * Returns true if a valid distortion lookup table was provided via
 * set_undist_lut(), false otherwise.
 */
INLINE bool ProjectionScreen::
has_undist_lut() const {
  return _has_undist_lut;
}

/**
 * Returns the distortion lookup table provided via set_undist_lut(), if any.
 */
INLINE const PfmFile &ProjectionScreen::
get_undist_lut() const {
  return _undist_lut;
}

/**
 * Specifies the name of the texture coordinates that are generated by this
 * particular ProjectionScreen.  This can be used in the presence of
 * multitexturing to compute the UV's for just a subset of all of the active
 * stages of the multitexture pipeline.
 */
INLINE void ProjectionScreen::
set_texcoord_name(const std::string &texcoord_name) {
  _texcoord_name = InternalName::get_texcoord_name(texcoord_name);
  _stale = true;
}

/**
 * Returns the name of the texture coordinates that will be generated by this
 * particular ProjectionScreen, as set by set_texcoord_name().
 */
INLINE std::string ProjectionScreen::
get_texcoord_name() const {
  return _texcoord_name->get_name();
}

/**
 * Some OpenGL graphics drivers are known to invert the framebuffer image when
 * they copy it to texture.  (This is arguably a problem with the OpenGL spec,
 * which seems to be unclear about the proper ordering of pixels in this
 * operation.)
 *
 * In any case, set this true to compensate for this effect by inverting the
 * UV's of the projection screen.  The default is taken from the Configrc
 * variable project-invert-uvs.
 */
INLINE void ProjectionScreen::
set_invert_uvs(bool invert_uvs) {
  _invert_uvs = invert_uvs;
  _stale = true;
}


/**
 * Returns whether this screen is compensating for a graphics driver inverting
 * the framebuffer image.  See set_invert_uvs().
 */
INLINE bool ProjectionScreen::
get_invert_uvs() const {
  return _invert_uvs;
}

/**
 * Set this true to force 3-D texture coordinates to be created for the
 * geometry.  When this is true and the geometry has only 2-D texture
 * coordinates, those texture coordinates are dumped in favor of 3-D
 * coordinates.  When this is false, whatever texture coordinates already
 * exist are preserved as-is.
 */
INLINE void ProjectionScreen::
set_texcoord_3d(bool texcoord_3d) {
  _texcoord_3d = texcoord_3d;
  _stale = true;
}


/**
 * See set_texcoord_3d().
 */
INLINE bool ProjectionScreen::
get_texcoord_3d() const {
  return _texcoord_3d;
}

/**
 * Specifies whether vertex-based vignetting should be on.  When this is
 * enabled, vertex color will be set on the screen vertices to color the
 * screen two distinct colors, usually white and black, for the parts of the
 * screen in front of and outside the lens' frustum, respectively.  When this
 * is not enabled, the screen color will be left alone.
 *
 * This effect generally looks terrible, but it does at least make the
 * boundaries of the lens clear.
 */
INLINE void ProjectionScreen::
set_vignette_on(bool vignette_on) {
  _vignette_on = vignette_on;
  _stale = true;
}


/**
 * Returns true if vertex-based vignetting is on, false otherwise.  See
 * set_vignette_on().
 */
INLINE bool ProjectionScreen::
get_vignette_on() const {
  return _vignette_on;
}

/**
 * Specifies the color the screen will be painted at the portions outside of
 * the lens' frustum; i.e.  where the lens can't see it or illuminate it.
 * This color is only used if the vignette_on flag is true; see
 * set_vignette_on().
 */
INLINE void ProjectionScreen::
set_vignette_color(const LColor &vignette_color) {
  _vignette_color = vignette_color;
  _stale = true;
}

/**
 * Returns the color the screen will be painted at the portions outside of the
 * lens' frustum.  See set_vignette_color().
 */
INLINE const LColor &ProjectionScreen::
get_vignette_color() const {
  return _vignette_color;
}

/**
 * Specifies the color the screen will be painted at the portions outside of
 * the lens' frustum; i.e.  where the lens can't see it or illuminate it.
 * This color is only used if the vignette_on flag is true; see
 * set_vignette_on().
 */
INLINE void ProjectionScreen::
set_frame_color(const LColor &frame_color) {
  _frame_color = frame_color;
  _stale = true;
}

/**
 * Returns the color the screen will be painted at the portions outside of the
 * lens' frustum.  See set_frame_color().
 */
INLINE const LColor &ProjectionScreen::
get_frame_color() const {
  return _frame_color;
}

/**
 * Sets the auto_recompute flag.  When this is true, the ProjectionScreen will
 * always be recomputed if necessary before the frame is drawn; when it is
 * false, an explicit call to recompute_if_stale() may be required.
 */
INLINE void ProjectionScreen::
set_auto_recompute(bool auto_recompute) {
  _auto_recompute = auto_recompute;
}


/**
 * Returns the auto_recompute flag.  When this is true, the ProjectionScreen
 * will always be recomputed if necessary before the frame is drawn; when it
 * is false, an explicit call to recompute_if_stale() may be required.
 */
INLINE bool ProjectionScreen::
get_auto_recompute() const {
  return _auto_recompute;
}


/**
 * Returns an UpdateSeq corresponding to the last time a screen mesh was
 * generated for the ProjectionScreen.  Each time generate_screen() is called,
 * this number is incremented; this allows other objects (like
 * NonlinearImager) to know when they need to recompute themselves.
 */
INLINE const UpdateSeq &ProjectionScreen::
get_last_screen() const {
  return _last_screen;
}
